#
# Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

cmake_minimum_required(VERSION 3.8...3.22)

# Project
project(boost_mysql VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)

# Determine if we're the top-level project. Used for extra functionality and Boost dependency management.
# We've got the following use cases:
#  1. We're building the superproject, and it has called add_subdirectory() on us. BOOST_SUPERPROJECT_VERSION defined.
#  2. Someone's calling add_subdirectory() on us and doesn't want us to find_package Boost, e.g. the cmake subdir test.
#  3. We're the main project and we want to use an installed version of Boost (e.g. normal development)
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    set(BOOST_MYSQL_IS_ROOT ON)
else()
    set(BOOST_MYSQL_IS_ROOT OFF)
endif()

# Library
add_library(boost_mysql INTERFACE)
add_library(Boost::mysql ALIAS boost_mysql)

# Dependencies
if (BOOST_MYSQL_IS_ROOT)
    # If we're the root project, error if a dependency is not found
    find_package(Boost ${BOOST_MYSQL_VERSION} REQUIRED COMPONENTS headers system)
    find_package(Threads REQUIRED)
    find_package(OpenSSL REQUIRED)
    target_link_libraries(
        boost_mysql
        INTERFACE
        Boost::headers
        Boost::system
        Threads::Threads
        OpenSSL::Crypto
        OpenSSL::SSL
    )
else()
    # If we're in the superproject or called from add_subdirectory,
    # Boost dependencies should be already available.
    # If other dependencies are not found, we bail out
    find_package(Threads)
    if(NOT Threads_FOUND)
        message(STATUS "Boost.MySQL has been disabled, because the required package Threads hasn't been found")
        return()
    endif()
    find_package(OpenSSL)
    if(NOT OpenSSL_FOUND)
        message(STATUS "Boost.MySQL has been disabled, because the required package OpenSSL hasn't been found")
        return()
    endif()

    # This is generated by boostdep
    target_link_libraries(
        boost_mysql
        INTERFACE
        Boost::asio
        Boost::assert
        Boost::config
        Boost::core
        Boost::describe
        Boost::mp11
        Boost::system
        Boost::throw_exception
        Boost::variant2
        Boost::endian
        Boost::lexical_cast
        Threads::Threads
        OpenSSL::Crypto
        OpenSSL::SSL
    )
endif()

# Includes & features
if (BOOST_MYSQL_IS_ROOT)
    target_include_directories(boost_mysql SYSTEM INTERFACE include)
else()
    target_include_directories(boost_mysql INTERFACE include)
endif()
target_compile_features(boost_mysql INTERFACE cxx_std_11)

# If we are the top-level project, enable CTest and some extra options used in CI
if(BOOST_MYSQL_IS_ROOT)
    include(CTest)

    # Don't run integration testing unless explicitly requested
    option(BOOST_MYSQL_INTEGRATION_TESTS OFF "Whether to build and run integration tests or not")
    mark_as_advanced(BOOST_MYSQL_INTEGRATION_TESTS)

    # Valgrind tests and Valgrind-friendly code (e.g. mark SSL buffers as initialized)
    option(BOOST_MYSQL_VALGRIND_TESTS OFF "Whether to run Valgrind tests or not (requires Valgrind)")
    mark_as_advanced(BOOST_MYSQL_VALGRIND_TESTS)
    
    # Build with coverage
    option(BOOST_MYSQL_COVERAGE OFF "Whether to build using coverage")
    mark_as_advanced(BOOST_MYSQL_COVERAGE)
endif()

# Examples and tests
if(BUILD_TESTING)
    # Contains some functions to share code between examples and tests
    include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/test_utils.cmake)

    # Custom target tests; required by the Boost superproject
    if(NOT TARGET tests)
        add_custom_target(tests)
    endif()

    # All examples require a real server to run
    add_subdirectory(test)
    if (BOOST_MYSQL_INTEGRATION_TESTS)
        add_subdirectory(example)
    endif()

endif()
